package simplifiedPastry.simulation;

import java.io.IOException;
import java.io.Serializable;
import java.net.InetAddress;

import simplifiedPastry.LeafSet;
import simplifiedPastry.Message;
import simplifiedPastry.MessageListener;
import simplifiedPastry.Node;
import simplifiedPastry.NodeId;
import simplifiedPastry.RoutingTable;
import simplifiedPastry.exceptions.NodeStateException;
import simplifiedPastry.ProtocolVariables;

public class NodeTest extends Node implements Serializable {
	private static final long serialVersionUID = -7185715948728595985L;
	private MessageRegistrator registrator;
	
	public NodeTest(NodeId nodeId, InetAddress inetAddress, int port) {
		super(nodeId, inetAddress, port, ProtocolVariables.defaultConnectTimeout,
				ProtocolVariables.defaultSendWaitTimeout);
		
		registrator = new MessageRegistrator(this);
		
		try {
			setMessageListener(registrator);
		} catch (NodeStateException e) { }
	}
	
	public int getSendNum() {
		return registrator.getSendNum();
	}
	
	public int getKSearchNum() {
		return registrator.getKSearchNum();
	}
	
	public int getSendNumTimeout() {
		return registrator.getSendNumTimeout();
	}
	
	public int getKSearchTimeout() {
		return registrator.getKSearchTimeout();
	}
	
	public int getNodeNotFoundNum() {
		return registrator.getNodeNotFound();
	}
	
	private class MessageRegistrator implements MessageListener, Serializable {
		private static final long serialVersionUID = -842916798424393040L;
		private int sendNum;
		private int kSearchNum;
		private int sendNumTimeout;
		private int kSearchTimeout;
		private int nodeNotFound;
		private Node node;
		public MessageRegistrator(Node n) {
			node = n;
			sendNum = 0;
			kSearchNum = 0;
			sendNumTimeout = 0;
			kSearchTimeout = 0;
			nodeNotFound = 0;
		}
		
		public synchronized int getSendNum() {
			return sendNum;
		}
		
		public synchronized int getKSearchNum() {
			return kSearchNum;
		}
		
		public synchronized int getSendNumTimeout() {
			return sendNumTimeout;
		}
		
		public synchronized int getKSearchTimeout() {
			return kSearchTimeout;
		}
		
		public synchronized int getNodeNotFound() {
			return nodeNotFound;
		}
		
		@Override
		public void kSearchRecv(NodeId[] nodeArray) {
			++kSearchNum;
		}

		@Override
		public void kSearchTimeout(NodeId serachId) {
			++kSearchTimeout;
		}

		@Override
		public void messageAccepted(Message message) {
//			System.out.println("REGISTRATOR - messageAccepted");
			++sendNum;
		}

		@Override
		public void messageRecv(Message message, NodeId recvId) {
			System.out.println("Node(" + node.getId() + ") otrzymalem: '" + new String(message.getByte()) + "'");
		}

		@Override
		public void messageTimeout(Message message) {
			++sendNumTimeout;
		}

		@Override
		public void nodeNotFound(NodeId recvId) {
			++nodeNotFound;
		}
		
		@Override
		public void ioError(IOException exception) {
			
		}
	}
	
	public boolean equals(NodeId node) {
		return nodeId.equals(node);
	}
	
	public boolean equals(Object o) {
        if (!(o instanceof NodeTest))
            return false;
        NodeTest n = (NodeTest)o;
        return registrator.equals(n.registrator) &&
        		((Node)n).equals(((Node)this));
    }

	public RoutingTable getRoutingtable() {
		return routingTable;
	}

	public LeafSet getLeafSet() {
		return leafSet;
	}
}
